package com.boe.csb.core.service.csb;

import com.alibaba.csb.console.sdk.Result;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.boe.csb.core.common.CsbConstants;
import com.boe.csb.core.common.status.AdminUserRole;
import com.boe.csb.core.common.status.PublishStatusEnum;
import com.boe.csb.core.common.utils.CsbApiCaller;
import com.boe.csb.core.common.utils.MailTemplate;
import com.boe.csb.core.dao.*;
import com.boe.csb.core.entity.po.BoeApiInfo;
import com.boe.csb.core.entity.po.BoeUser;
import com.boe.csb.core.entity.po.UserOperateLog;
import com.boe.csb.core.service.SendMailService;
import com.boe.csb.core.service.api.BoeApiInfoService;
import com.boe.csb.core.service.api.BoeApiPopularService;
import com.boe.csb.core.service.user.BoeUserService;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.*;

/**
 * Created by tianxiang.luo on 16/12/4.
 * 管理员审核服务
 */

@Service("csbAuditApiService")
public class CsbAuditApiService {


    @Autowired
    private BoeUserMapper boeUserMapper;
    @Autowired
    private BoeApiInfoMapper boeApiInfoMapper;
    @Autowired
    private BoeApiPopularService boeApiPopularService;
    @Autowired
    private BoeUserService boeUserService;
    @Autowired
    private UserOperateLogMapper userOperateLogMapper;
    @Autowired
    private BoeApiInfoService boeApiInfoService;
    @Autowired
    private SendMailService sendMailService;

    //查询服务列表
    private static final String ADMIN_FIND_SERVICES = "/api/admin/service/find";
    //管理员审批服务
    private static final String APPROVE_SERVICE = "/api/admin/service/approvePub";


    /**
     * 服务列表
     */
    public Result adminFindService(String userId, Integer pageNum, String serviceName, String alias, String showDelService, String showPendingServiceOnly) {
        Map<String, String> findMap = new HashMap<>();
        findMap.put("csbId", CsbApiCaller.CSB_ID);
        findMap.put("userId", userId);
        findMap.put("pageNum", pageNum.toString());
        if (alias != null) {
            findMap.put("alias", alias);
        }
        if (serviceName != null) {
            findMap.put("serviceName", serviceName);
        }
        if (showDelService != null) {
            findMap.put("showDelService", showDelService);
        }
        if (showPendingServiceOnly != null) {
            findMap.put("showPendingServiceOnly", showPendingServiceOnly);
        }
        Result result = CsbApiCaller.callCsbGetApi(ADMIN_FIND_SERVICES, findMap);
        if (result.isSuccess() && !CollectionUtils.isEmpty(result.getData().getJSONArray("services"))) {
            JSONArray services = result.getData().getJSONArray("services");
            Map<Long, JSONObject> map = new HashMap<>();
            List<Long> serviceIdList = new ArrayList<>();
            List<String> userIdList = new ArrayList<>();
            for (Object obj : services) {
                JSONObject jsonObject = (JSONObject) obj;
                Long serviceId = jsonObject.getLong("id");
                String uId = jsonObject.getString("userId");
                map.put(serviceId, jsonObject);
                serviceIdList.add(serviceId);
                userIdList.add(uId);
            }
            Map<Long, BoeUser> userMap = getUserMapByIdList(userIdList);
            BoeApiInfoCriteria criteria = new BoeApiInfoCriteria();
            criteria.createCriteria().andCsbApiIdIn(serviceIdList);
            List<BoeApiInfo> boeApiInfoList = boeApiInfoMapper.selectByExample(criteria);
            for (BoeApiInfo info : boeApiInfoList) {
                JSONObject jsonObject = map.get(info.getCsbApiId());
                BoeUser boeUser = userMap.get(info.getUserId());
                if (boeUser != null) {
                    jsonObject.put("publishUser", boeUser.getEmail());
                }
                jsonObject.put("isRecommend", info.getIsRecommend());
            }
        } 
        return result;
    }


    public Map<Long, BoeUser> getUserMapByIdList(List<String> idList) {
        List<String> emailList = new ArrayList<>();
        List<Long> userIdList = new ArrayList<>();
        for (String id : idList) {
            emailList.add(id);
            try {
                Long tmp = Long.valueOf(id);
                userIdList.add(tmp);
            } catch (NumberFormatException e) {
                emailList.add(id);
            }
        }
        BoeUserCriteria boeUserCriteria = new BoeUserCriteria();
        Map<Long, BoeUser> map = new HashMap<>();
        if (!CollectionUtils.isEmpty(emailList)) {
            boeUserCriteria.createCriteria().andEmailIn(emailList);
            List<BoeUser> boeUserList = boeUserMapper.selectByExample(boeUserCriteria);
            if (!CollectionUtils.isEmpty(boeUserList)) {
                for (BoeUser boeUser : boeUserList) {
                    map.put(boeUser.getId(), boeUser);
                }
            }
        }
        if (!CollectionUtils.isEmpty(userIdList)) {
            boeUserCriteria.clear();
            boeUserCriteria.createCriteria().andIdIn(userIdList);
            List<BoeUser> boeUserList1 = boeUserMapper.selectByExample(boeUserCriteria);
            if (!CollectionUtils.isEmpty(boeUserList1)) {
                for (BoeUser boeUser : boeUserList1) {
                    map.put(boeUser.getId(), boeUser);
                }
            }
        }
        return map;
    }

    public Result approveService(String userId, Long serviceId, String comment, boolean approveFlag) {
        List<Long> successIdList = new ArrayList<>();
        Map<String, String> map = new HashMap<>();
        map.put("csbId", CsbApiCaller.CSB_ID);
        map.put("userId", userId);
        map.put("serviceId", String.valueOf(serviceId));
        map.put("comments", comment);
        map.put("approveFlag", String.valueOf(approveFlag));
        Result result = CsbApiCaller.callCsbPostApi(APPROVE_SERVICE, map, "");

        //纪录日志
        String log = String.valueOf(serviceId);
        String userName = boeUserService.findBoeUser(userId).getEmail();
        BoeApiInfoCriteria infoCriteria = new BoeApiInfoCriteria();
        infoCriteria.createCriteria().andCsbApiIdEqualTo(serviceId);
        List<BoeApiInfo> boeApiInfoList = boeApiInfoMapper.selectByExample(infoCriteria);
        String boeApiName = "";

        if (!CollectionUtils.isEmpty(boeApiInfoList)) {
            String remark = String.format("管理员%s审核了服务:%s", userName, boeApiInfoList.get(0).getApiName());
            userOperateLogMapper.insert(new UserOperateLog(Long.valueOf(userId), userName, log, AdminUserRole.AUDIT_SERVICE.getRole(), remark, new Date()));
            boeApiName = boeApiInfoList.get(0).getApiName();
        }


        successIdList.add(serviceId);

        /**
         * 是否停止本地的热门服务
         */
        boeApiPopularService.updatePopularServices(approveFlag, successIdList);

        /**
         * 更新本地服务的状态
         */
        String apiStatus = approveFlag ? PublishStatusEnum.ACTIVE.getStatus() : PublishStatusEnum.REJECT.getStatus();
        boeApiInfoService.updateApiStatus(Arrays.asList(serviceId), apiStatus);

        /**
         * 发送邮件
         */
        String emailContent = MailTemplate.generateServiceAuditMail(approveFlag, boeApiName, "发布");

        //根据boeInfo取出useridList
        List<Long> userIdList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(boeApiInfoList)) {
            for (BoeApiInfo boeApiInfo : boeApiInfoList) {
                userIdList.add(boeApiInfo.getUserId());
            }

            if (!CollectionUtils.isEmpty(userIdList)) {
                BoeUserCriteria userCriteria = new BoeUserCriteria();
                userCriteria.createCriteria().andIdIn(userIdList);
                List<BoeUser> boeUserList = boeUserMapper.selectByExample(userCriteria);
                if (!CollectionUtils.isEmpty(boeUserList)) {
                    for (BoeUser boeUser : boeUserList) {
                        sendMailService.asyncSendMail(boeUser.getEmail(), CsbConstants.SERVICE_AUDIT_MAIL_SUBJECT, emailContent);
                    }
                }
            }
        }
        return result;
    }

    /**
     * 检查服务是否被订阅时是否需要审批
     */
    public boolean checkServiceIsAudit(Long serviceId) {
        if (serviceId == null)
            return true;
        BoeApiInfoCriteria criteria = new BoeApiInfoCriteria();
        criteria.createCriteria().andCsbApiIdEqualTo(serviceId);
        List<BoeApiInfo> boeApiInfoList = boeApiInfoMapper.selectByExample(criteria);
        if (!CollectionUtils.isEmpty(boeApiInfoList)) {
            return boeApiInfoList.get(0).getIsAudit();
        }
        return true;
    }

}
